﻿// Nova.CodeDOM usage examples.
// Copyright (C) 2007-2012 Inevitable Software, all rights reserved.
// Released under the Common Development and Distribution License, CDDL-1.0: http://opensource.org/licenses/cddl1.php

using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;

using Nova.CodeDOM;
using Nova.Utilities;

namespace Nova.Test
{
    /// <summary>
    /// This program contains tests for the Nova.CodeDOM C# object model library.
    /// </summary>
    class Program
    {
        #region /* MAIN METHOD */

        static void Main()
        {
            // Determine the application name and if we're running in VS
            string appName = AppDomain.CurrentDomain.FriendlyName;
            if (appName.EndsWith(".exe"))
                appName = appName.Substring(0, appName.Length - 4);
            if (appName.EndsWith(".vshost"))
                appName = appName.Substring(0, appName.Length - 7);

            // Change from the output directory to the project root
            Directory.SetCurrentDirectory(FileUtil.GetBaseDirectory());

            Version appVersion = typeof(Program).Assembly.GetName().Version;
            string appDescription = appName + " " + appVersion.Major + "." + appVersion.Minor;
            Console.WriteLine(appDescription + "  -  C# CodeDOM Test Utility.\nCopyright (C) 2011-2012 Inevitable Software, all rights reserved.");

            // Execute all public tests in this class
            Log.WriteLine("\nExecuting Nova.CodeDOM tests...\n");
            MethodInfo[] methodInfos = Assembly.GetExecutingAssembly().GetType("Nova.Test.Program").GetMethods(BindingFlags.Public | BindingFlags.Static);
            foreach (MethodInfo methodInfo in methodInfos)
            {
                Log.WriteLine("===== Executing Test: " + methodInfo.Name + " =====");
                try
                {
                    methodInfo.Invoke(null, null);
                }
                catch (Exception ex)
                {
                    Log.Exception(ex, "executing test");
                }
                Log.WriteLine("===== " + methodInfo.Name + " Completed =====\n");
            }

            // Wait for a key press before exiting if running in VS
            if (Debugger.IsAttached)
            {
                Console.WriteLine("DONE.  Press any key to exit.");
                Console.ReadKey();
            }
        }

        #endregion

        #region /* TESTS */

        /// <summary>
        /// Manually generate the Simple test and display it.
        /// </summary>
        public static void GenerateSimpleTest()
        {
            const string name = "Simple";
            Log.WriteLine("Generating code for '" + name + "'...");
            CodeObject codeObject = ManualTests.GenerateSimpleTest("name");
            Log.WriteLine(codeObject.AsText(CodeObject.RenderFlags.SuppressNewLine));
        }

        /// <summary>
        /// Manually generate the Method test and display it.
        /// </summary>
        public static void GenerateMethodTest()
        {
            const string name = "Method";
            Log.WriteLine("Generating code for '" + name + "'...");
            CodeObject codeObject = ManualTests.GenerateMethodTest("name");
            Log.WriteLine(codeObject.AsText(CodeObject.RenderFlags.SuppressNewLine));
        }

        /// <summary>
        /// Manually generate the code in FullTest.cs, save it in FullTest.generated.cs, and compare to FullTest.cs.
        /// </summary>
        public static void GenerateFullTest()
        {
            const string fileName = "FullTest.generated.cs";
            Log.WriteLine("Generating code for '" + fileName + "'...");
            CodeUnit codeUnit = ManualTests.GenerateFullTest(fileName);
            Log.WriteLine("Saving '" + fileName + "'...");
            codeUnit.Save();

            string file2 = FileUtil.FindFile("FullTest.cs");
            CompareFiles(fileName, file2);
        }

        private static void CompareFiles(string fileName1, string fileName2)
        {
            Log.WriteLine("Comparing '" + fileName1 + "' to '" + fileName2 + "'...");
            int line = 0;
            using (StreamReader fileStream1 = new StreamReader(fileName1))
            using (StreamReader fileStream2 = new StreamReader(fileName2))
            {
                while (!fileStream1.EndOfStream && !fileStream2.EndOfStream)
                {
                    string file1Line = fileStream1.ReadLine();
                    string file2Line = fileStream2.ReadLine();
                    ++line;
                    if (file1Line != file2Line)
                    {
                        Log.WriteLine("FAIL: Files differ at line " + line + "!");
                        return;
                    }
                }
                if (!fileStream1.EndOfStream)
                    Log.WriteLine("FAIL: First file is longer!");
                else if (!fileStream1.EndOfStream)
                    Log.WriteLine("FAIL: Second file is longer!");
                else
                    Log.WriteLine("PASS: Files are identical.");
            }
        }

        #endregion
    }
}
